﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Web;
using System.Drawing.Drawing2D;

namespace CoyoEden
{
	/// <summary>
	/// Common Utils
	/// </summary>
	public static partial class Utils
	{
		/// <summary>
		/// Generate a thumbnail from an image
		/// </summary>
		/// <remarks>
		///		1,Old way:
		///			thumbnail_image = original_image.GetThumbnailImage(new_width, new_height, null, System.IntPtr.Zero);
		///			We don't have to create a Thumbnail since the DrawImage method will resize, but the GetThumbnailImage looks better
		///			I've read about a problem with GetThumbnailImage. If a jpeg has an embedded thumbnail it will use and resize it which
		///			can result in a tiny 40x40 thumbnail being stretch up to our target size
		///		2,About graphic effects:
		///			http://weblogs.asp.net/bleroy/archive/2007/12/05/what-interpolationmode-and-compositingquality-to-use-when-generating-thumbnails-via-system-drawing.aspx
		/// </remarks>
		/// <returns></returns>
		public static Bitmap GenAThumbnail(Image originalImage,int targetHeight, int targetWidth,bool disposeInputImage)
		{
			//1,Resolving thumbnail's size and drawing point
			PointF drawDim=new PointF();
			Size thumbnailSize = GetThumbnailSize(originalImage.Height, originalImage.Width, targetHeight, targetWidth, out drawDim);

			Bitmap finalImage = null;
			finalImage = new Bitmap(thumbnailSize.Width, thumbnailSize.Height);
			using (Graphics graphic = Graphics.FromImage(finalImage))
			{
				//Graphic effects
				graphic.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, thumbnailSize.Width, thumbnailSize.Height));
				graphic.CompositingQuality = CompositingQuality.HighSpeed;
				graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
				graphic.CompositingMode = CompositingMode.SourceCopy;
				//Draw our finalImage according to the originalImage
				graphic.DrawImage(originalImage, (int)drawDim.X, (int)drawDim.Y, thumbnailSize.Width, thumbnailSize.Height);
			}
			if (disposeInputImage)
			{
				originalImage.Dispose();
			}
			return finalImage;
		}
		/// <summary>
		/// Generate a thumbnail from a httppostedfile.Use Request.Files["xxx"] to get this posted file;
		/// </summary>
		/// <returns></returns>
		public static Bitmap GenAThumbnail(HttpPostedFile imageFile,int targetHeight, int targetWidth)
		{
			Image srcImage = Image.FromStream(imageFile.InputStream);
			return GenAThumbnail(srcImage,targetHeight,targetWidth,true);
		}
		/// <summary>
		/// Generate a file name automatically
		/// </summary>
		/// <returns></returns>
		public static string RandomFileName() {
			Random random = new Random(unchecked((int)DateTime.Now.Ticks));
			Random random1=new Random();
			StringBuilder retVal = new StringBuilder();
			retVal.AppendFormat("{0}{1}{2}", (Environment.TickCount & int.MaxValue).ToString(),random.Next(1000,9999).ToString(),LETTERS[random1.Next(LETTERS.Length)].ToString());
			return retVal.ToString();
		}
		#region private helper methods
		/// <summary>
		/// Get thumbnail's new image size
		/// </summary>
		/// <param name="originalHeight"></param>
		/// <param name="originalWidth"></param>
		/// <param name="targetHeight"></param>
		/// <param name="targetWidth"></param>
		/// <param name="forceSquare"></param>
		/// <param name="imgDrawingStartPoint">Used in Graphic.DrawImage method</param>
		/// <returns></returns>
		private static Size GetThumbnailSize(int originalHeight, int originalWidth, int targetHeight, int targetWidth, out PointF imgDrawingStartPoint)
		{
			imgDrawingStartPoint = new PointF();
			// Calculate the new width and height
			int newWidth, newHeight;

			float targetRatio = (float)targetWidth / (float)targetHeight;
			float imageRatio = (float)originalWidth / (float)originalHeight;

			if (targetRatio > imageRatio)
			{
				newHeight = targetHeight;
				newWidth = (int)Math.Floor(imageRatio * (float)targetHeight);
			}
			else
			{
				newHeight = (int)Math.Floor((float)targetWidth / imageRatio);
				newWidth = targetWidth;
			}

			newWidth = newWidth > targetWidth ? targetWidth : newWidth;
			newHeight = newHeight > targetHeight ? targetHeight : newHeight;

			//Calculate drawing's starting poit
			int X = (targetWidth - newWidth) / 2;
			int Y = (targetHeight - newHeight) / 2;
			imgDrawingStartPoint.X = (float)X;
			imgDrawingStartPoint.Y = (float)Y;

			return new Size(newWidth, newHeight);

		}
		#endregion
	}
}
